package com.example.springboot.utils;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;

@Data
@AllArgsConstructor
@Slf4j
public class AliOssUtil {

    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;

    /**
     * 文件上传
     * @param bytes 文件字节数组
     * @param objectName OSS对象名称
     * @return 文件访问URL
     */
    public String upload(byte[] bytes, String objectName) {
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // 创建PutObject请求
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(bytes.length);
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes), metadata);

            // 生成访问URL（可设置过期时间）
            Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000 * 24 * 365 * 10); // 10年有效期
            URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration);
            return url.toString();

        } catch (OSSException oe) {
            log.error("OSS异常: {}", oe.getMessage());
            throw new RuntimeException("文件上传失败: " + oe.getErrorMessage());
        } catch (ClientException ce) {
            log.error("客户端异常: {}", ce.getMessage());
            throw new RuntimeException("文件上传失败: " + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * 下载文件
     * @param fileKey 文件在OSS中的key
     * @return 文件输入流
     */
    public InputStream download(String fileKey) {
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try {
            OSSObject ossObject = ossClient.getObject(bucketName, fileKey);
            return new OSSObjectWrapper(ossClient, ossObject);
        } catch (OSSException | ClientException e) {
            log.error("文件下载失败: {}", e.getMessage());
            throw new RuntimeException("文件下载失败: " + e.getMessage());
        }
    }

    /**
     * 删除文件
     * @param fileKey 文件在OSS中的key
     */
    public void delete(String fileKey) {
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try {
            ossClient.deleteObject(bucketName, fileKey);
        } catch (OSSException | ClientException e) {
            log.error("文件删除失败: {}", e.getMessage());
            throw new RuntimeException("文件删除失败: " + e.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * 包装类，用于正确关闭OSSClient和OSSObject
     */
    private static class OSSObjectWrapper extends InputStream {
        private final OSS ossClient;
        private final OSSObject ossObject;
        private final InputStream inputStream;

        public OSSObjectWrapper(OSS ossClient, OSSObject ossObject) {
            this.ossClient = ossClient;
            this.ossObject = ossObject;
            this.inputStream = ossObject.getObjectContent();
        }

        @Override
        public int read() throws IOException {
            return inputStream.read();
        }

        @Override
        public void close() throws IOException {
            try {
                inputStream.close();
            } finally {
                ossObject.close();
                ossClient.shutdown();
            }
        }

        // 其他InputStream方法的实现...
    }
}